#include "Main.h"
#include "wx/odcombo.h"
DECLARE_APP(MyApp)
IMPLEMENT_APP(MyApp)




#include <wx/combo.h>
#include <wx/listctrl.h>

class wxCheckListViewComboPopup : public wxCheckListBox, public wxComboPopup
{
public:

    // Initialize member variables
    virtual void Init()
    {
        m_value = -1;
    }

    // Create popup control
    virtual bool Create(wxWindow* parent)
    {
		bool bCreated = wxCheckListBox::Create(parent,1,wxPoint(0,0),wxDefaultSize);
		return bCreated;
    }

    // Return pointer to the created control
    virtual wxWindow *GetControl() { return this; }

    // Translate string into a list selection
    virtual void SetStringValue(const wxString& s)
    {
        //int n = wxCheckListBox::FindItem(-1,s);
        //if ( n >= 0 && n < wxCheckListBox::GetItemCount() )
            //wxCheckListBox::Select(n);
    }

    // Get list selection as a string
    virtual wxString GetStringValue() const
    {
        //if ( m_value >= 0 )
        //    return wxCheckListBox::GetItemText(m_value);
        return wxEmptyString;
    }

    // Do mouse hot-tracking (which is typical in list popups)
    void OnMouseMove(wxMouseEvent& event)
    {
        // TODO: Move selection to cursor
    }

    // On mouse left up, set the value and close the popup
    void OnMouseClick(wxMouseEvent& event)
    {
		//this->OnLeftClick(event );



		int nItem = HitTest(event.GetX(), event.GetY());

		if ( nItem != wxNOT_FOUND )
		{
			wxRect rect;
			GetItemRect(nItem, rect);

			// convert item rect to check mark rect
			wxSize size = wxRendererNative::Get().GetCheckBoxSize(this);
			rect.x += 1;//CHECKMARK_EXTRA_SPACE;
			rect.y += (rect.GetHeight() - size.GetHeight()) / 2;
			rect.SetSize(size);

			if ( rect.Contains(event.GetX(), event.GetY()) )
			{
				// people expect to get "kill focus" event for the currently
				// focused control before getting events from the other controls
				// and, equally importantly, they may prevent the focus change from
				// taking place at all (e.g. because the old control contents is
				// invalid and needs to be corrected) in which case we shouldn't
				// generate this event at all
				SetFocus();
				//if ( FindFocus() == this )
				//{
					Toggle(nItem);
					SendEvent(nItem);

					// scroll one item down if the item is the last one
					// and isn't visible at all
					int h;
					GetClientSize(NULL, &h);
					if ( rect.GetBottom() > h )
						ScrollLines(1);
				//}
			}
			else
			{
				// implement default behaviour: clicking on the item selects it
				event.Skip();
			}
		}
		else
		{
			// implement default behaviour on click outside of client zone
			event.Skip();
		}

	//	wxCheckListBox::HandleMouseEvent(wxEVT_LEFT_UP, event.GetX(), event.GetY(), 0);
        //m_value = wxCheckListBox::GetFirstSelected();

        // TODO: Send event as well

        //Dismiss();
    }

protected:

    int             m_value; // current item index

private:
    DECLARE_EVENT_TABLE()
};

BEGIN_EVENT_TABLE(wxCheckListViewComboPopup, wxCheckListBox)
    EVT_MOTION(wxCheckListViewComboPopup::OnMouseMove)
    EVT_LEFT_DOWN(wxCheckListViewComboPopup::OnMouseClick)
END_EVENT_TABLE()







class wxComboBoxWithCheckListBox : public wxPGChoiceEditor
{
	DECLARE_DYNAMIC_CLASS(wxComboBoxWithCheckListBox);

	wxComboBoxWithCheckListBox() {}
	virtual ~wxComboBoxWithCheckListBox() {}

	virtual wxPGWindowList CreateControls( class wxPropertyGrid * propGrid,
											class wxPGProperty* property,
												const wxPoint& pos,
												const wxSize& sz ) const;

	// CreateControls calls this with CB_READONLY in extraStyle
	wxWindow* CustomCreateControlsBase( wxPropertyGrid* propGrid,
													wxPGProperty* property,
													const wxPoint& pos,
													const wxSize& sz,
													long extraStyle ) const;

};
IMPLEMENT_DYNAMIC_CLASS(wxComboBoxWithCheckListBox, wxPGChoiceEditor)



wxPGWindowList wxComboBoxWithCheckListBox::CreateControls( wxPropertyGrid* propGrid,
	wxPGProperty* property,
	const wxPoint& pos,
	const wxSize& sz ) const
{

	// Create the 'primary' editor control (textctrl in this case)
	wxPGWindowList wndList = CustomCreateControlsBase ( propGrid, property, pos, sz, 0 );


	wxCheckListViewComboPopup* popupCtrl = new wxCheckListViewComboPopup();



	((wxComboCtrl*)(wndList.m_primary))->SetPopupControl(popupCtrl);


	for ( int i = 0; i < CDataInterface::getSingletonPtr()->getCityImprovementData().size; i++ )
	{
		CDataCityImprovement* pData = CDataInterface::getSingletonPtr()->getCityImprovementData ( i );
		irr::core::stringw t ( pData->GetLocale( pData->mDescription ) );

		popupCtrl->Append ( t.c_str() );
	}




	return wndList;
}

#define wxPG_CHOICEXADJUST           0
#define wxPG_CHOICEYADJUST           0

// CreateControls calls this with CB_READONLY in extraStyle
wxWindow* wxComboBoxWithCheckListBox::CustomCreateControlsBase( wxPropertyGrid* propGrid,
                                                wxPGProperty* property,
                                                const wxPoint& pos,
                                                const wxSize& sz,
                                                long extraStyle ) const
{
    // Since it is not possible (yet) to create a read-only combo box in
    // the same sense that wxTextCtrl is read-only, simply do not create
    // the control in this case.
    if ( property->HasFlag(wxPG_PROP_READONLY) )
        return NULL;

    const wxPGChoices& choices = property->GetChoices();
    wxString defString;
    int index = property->GetChoiceSelection();

    int argFlags = 0;
    if ( !property->HasFlag(wxPG_PROP_READONLY) &&
         !property->IsValueUnspecified() )
        argFlags |= wxPG_EDITABLE_VALUE;
    defString = property->GetValueAsString(argFlags);

    wxArrayString labels = choices.GetLabels();

    wxComboCtrl* cb;

    wxPoint po(pos);
    wxSize si(sz);
    po.y += wxPG_CHOICEYADJUST;
    si.y -= (wxPG_CHOICEYADJUST*2);

    po.x += wxPG_CHOICEXADJUST;
    si.x -= wxPG_CHOICEXADJUST;
    wxWindow* ctrlParent = propGrid->GetPanel();

    int odcbFlags = extraStyle | wxBORDER_NONE | wxTE_PROCESS_ENTER;

    if ( (property->GetFlags() & wxPG_PROP_USE_DCC) &&
         (property->IsKindOf(CLASSINFO(wxBoolProperty)) ) )
        odcbFlags |= wxODCB_DCLICK_CYCLES;

    //
    // If common value specified, use appropriate index
    unsigned int cmnVals = property->GetDisplayedCommonValueCount();
    if ( cmnVals )
    {
        if ( !property->IsValueUnspecified() )
        {
            int cmnVal = property->GetCommonValue();
            if ( cmnVal >= 0 )
            {
                index = labels.size() + cmnVal;
            }
        }

        unsigned int i;
        for ( i=0; i<cmnVals; i++ )
            labels.Add(propGrid->GetCommonValueLabel(i));
    }

    cb = new wxComboCtrl();
#ifdef __WXMSW__
    cb->Hide();
#endif
    cb->Create(ctrlParent,
               wxPG_SUBID1,
               wxString(),
               po,
               si,
               odcbFlags);

    //cb->SetButtonPosition(si.y,0,wxRIGHT);
    cb->SetMargins(wxPG_XBEFORETEXT-1);

    // Set hint text
    cb->SetHint(property->GetHintText());

    //wxPGChoiceEditor_SetCustomPaintWidth( propGrid, cb,
                                      //    property->GetCommonValue() );

    /*if ( index >= 0 && index < (int)cb->GetCount() )
    {
        cb->SetSelection( index );
        if ( !defString.empty() )
            cb->SetValue( defString );
    }
    else if ( !(extraStyle & wxCB_READONLY) && !defString.empty() )
    {
        propGrid->SetupTextCtrlValue(defString);
        cb->SetValue( defString );
    }
    else
    {
        cb->SetSelection( -1 );
    }*/

#ifdef __WXMSW__
    cb->Show();
#endif

    return (wxWindow*) cb;
}



class wxMultiButtonTextCtrlEditor : public wxPGComboBoxEditor
{
	DECLARE_DYNAMIC_CLASS(wxMultiButtonTextCtrlEditor);
public:
	wxMultiButtonTextCtrlEditor() {}
	virtual ~wxMultiButtonTextCtrlEditor() {}

	virtual wxPGWindowList CreateControls( class wxPropertyGrid * propGrid,
											class wxPGProperty* property,
												const wxPoint& pos,
												const wxSize& sz ) const;

		virtual bool OnEvent( wxPropertyGrid* propGrid,
								wxPGProperty* property,
								wxWindow* ctrl,
								wxEvent& event ) const;

};

IMPLEMENT_DYNAMIC_CLASS(wxMultiButtonTextCtrlEditor, wxPGComboBoxEditor)

wxPGWindowList wxMultiButtonTextCtrlEditor::CreateControls( wxPropertyGrid* propGrid,
	wxPGProperty* property,
	const wxPoint& pos,
	const wxSize& sz ) const
{
	// Create and populate buttons-subwindow
	wxPGMultiButton* buttons = new wxPGMultiButton( propGrid, sz );

	// Add two regular buttons
	buttons->Add( wxT("+") );
	buttons->Add( wxT("-") );

	// Add a bitmap button
	//buttons->Add( wxArtProvider::GetBitmap(wxART_FOLDER) );

	// Create the 'primary' editor control (textctrl in this case)
	wxPGWindowList wndList = wxPGComboBoxEditor::CreateControls
		( propGrid, property, pos, buttons->GetPrimarySize() );

	// Finally, move buttons-subwindow to correct position and make sure
	// returned wxPGWindowList contains our custom button list.
	buttons->Finalize(propGrid, pos);

	wndList.SetSecondary( buttons );
	return wndList;
}

bool wxMultiButtonTextCtrlEditor::OnEvent( wxPropertyGrid* propGrid,
	wxPGProperty* property,
	wxWindow* ctrl,
	wxEvent& event ) const
{
	if ( event.GetEventType() == wxEVT_COMMAND_BUTTON_CLICKED )
	{
		wxPGMultiButton* buttons = (wxPGMultiButton*) propGrid->GetEditorControlSecondary();

		if ( event.GetId() == buttons->GetButtonId(0) )
		{
			CDataUnit* pData = CDataInterface::getSingletonPtr()->getUnitData(0);
			irr::core::stringw t ( pData->GetLocale( pData->mDescription ) );

			CPlayer* pPlayer = CGlobals::getSingletonPtr()->mPlayerList [ 0 ];

			((CCivilization*)pPlayer)->AddUnit (pData, ((MyFrame*)propGrid->GetParent())->GetSelectedTile());

			// Here we a new unit to the tile
			property->AddChoice( t.c_str() );
			property->SetChoiceSelection ( ( property->GetChoices().GetCount() - 1 ) );

			return true;

		}
		if ( event.GetId() == buttons->GetButtonId(1) )
		{
			// Delete the selected unit
			property->DeleteChoice( property->GetChoiceSelection() );
			property->SetChoiceSelection ( ( property->GetChoices().GetCount() - 1 ) );
			return true;

		}
/*
// 		if ( event.GetId() == buttons->GetButtonId(2) )
// 		{
// 			// Do something when third button is pressed
// 
// 		}
*/
	}
	return wxPGComboBoxEditor::OnEvent(propGrid, property, ctrl, event);
}

wxPGEditor* m_pSampleMultiButtonEditor = NULL;
wxPGEditor* m_pSampleXomboBoxCheckListBoxEditor = NULL;

bool MyApp::OnInit ( void )
{
	if ( wxApp::OnInit() == false )
		return false;

    MyFrame *frame = new MyFrame( "IndieCiv Editor", 
         wxPoint(50,50), wxSize(800,600) );
    frame->Show(TRUE);
    SetTopWindow(frame);

	return true;
}



int MyApp::FilterEvent(wxEvent& event)
{
	//wxWindow* pTopWindow = this->Get();

    if ( event.GetEventType() == wxEVT_KEY_DOWN )
    {
		irr::SEvent irrEvt;
		irrEvt.EventType	= irr::EET_KEY_INPUT_EVENT;
		irrEvt.KeyInput.Key = (irr::EKEY_CODE)((wxKeyEvent&)event).GetRawKeyCode();
		
		irrEvt.KeyInput.Char = (char)((wxKeyEvent&)event).GetRawKeyCode();
		irrEvt.KeyInput.PressedDown = true;
		irrEvt.KeyInput.Control = ((((wxKeyEvent&)event).GetModifiers() & wxMOD_CONTROL ) != 0); 
		irrEvt.KeyInput.Shift = ((((wxKeyEvent&)event).GetModifiers() & wxMOD_SHIFT) != 0);

		if ( irrEvt.KeyInput.Key >= 0 && irrEvt.KeyInput.Key < irr::KEY_KEY_CODES_COUNT )
		{
			CGlobals::getSingletonPtr()->mIrrDevice->postEventFromUser(irrEvt);
			//return true;
		}
    }
	else if ( event.GetEventType() == wxEVT_KEY_UP )
	{
		irr::SEvent irrEvt;
		irrEvt.EventType	= irr::EET_KEY_INPUT_EVENT;
		irrEvt.KeyInput.Key = (irr::EKEY_CODE)((wxKeyEvent&)event).GetRawKeyCode();
		irrEvt.KeyInput.Char = (char)((wxKeyEvent&)event).GetRawKeyCode();
		irrEvt.KeyInput.PressedDown = false;
		irrEvt.KeyInput.Control = ((((wxKeyEvent&)event).GetModifiers() & wxMOD_CONTROL ) != 0); 
		irrEvt.KeyInput.Shift = ((((wxKeyEvent&)event).GetModifiers() & wxMOD_SHIFT) != 0);

		if ( irrEvt.KeyInput.Key >= 0 && irrEvt.KeyInput.Key < irr::KEY_KEY_CODES_COUNT )
		{
			CGlobals::getSingletonPtr()->mIrrDevice->postEventFromUser(irrEvt);
			//return true;
		}
		//return true;
	}
 
    return wxApp::FilterEvent(event);
}

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
	EVT_SHOW(MyFrame::OnShow)
	EVT_MENU(ID_Load, MyFrame::OnLoad)
	EVT_MENU(ID_Save, MyFrame::OnSave)
	EVT_MENU(ID_SaveAs, MyFrame::OnSaveAs)
	EVT_MENU(ID_ImportMap, MyFrame::OnImportMap)
	EVT_MENU(ID_ImportCivIII, MyFrame::OnImportCivIII)
	EVT_MENU(ID_ClearMap, MyFrame::OnClearMap)
    EVT_MENU(ID_About, MyFrame::OnAbout)
	EVT_MENU(ID_EditModProperties, MyFrame::OnEditModProperties)
	EVT_MENU(ID_EditRules, MyFrame::OnEditRules)
	EVT_MENU(ID_EditArtDefines, MyFrame::OnEditArtDefines)
	EVT_MENU(ID_ScenarioProperties, MyFrame::OnScenarioProperties)
	EVT_MENU(ID_CustomRules, MyFrame::OnCustomRules)
	EVT_MENU(wxID_ANY, MyFrame::OnTerrainSelect)
    EVT_AUITOOLBAR_RIGHT_CLICK(ID_TerrainMode, MyFrame::OnDropDownToolbarItem)
    EVT_AUITOOLBAR_RIGHT_CLICK(ID_OverlayMode, MyFrame::OnDropDownToolbarItem)
	EVT_AUITOOLBAR_RIGHT_CLICK(ID_ResourceMode, MyFrame::OnDropDownToolbarItem)
    EVT_AUITOOLBAR_RIGHT_CLICK(ID_CityMode, MyFrame::OnDropDownToolbarItem)
    EVT_AUITOOLBAR_RIGHT_CLICK(ID_TerritoryMode, MyFrame::OnDropDownToolbarItem)
	EVT_PG_CHANGED(PGID, MyFrame::OnPGChanged)

	// This occurs when property's editor button (if any) is clicked.
	EVT_BUTTON( PGID, MyFrame::OnPropertyGridButtonClick )

END_EVENT_TABLE()

MyFrame::MyFrame ( const wxString& title, const wxPoint& pos, const wxSize& size ) : wxFrame ( ( wxFrame * ) NULL, -1, title, pos, size )
{
	wxMenuItem* pMenuItem = NULL;

	mMenuBar = new wxMenuBar;

    wxMenu *menuFile = new wxMenu;
    menuFile->Append( ID_Load, "&Load...", "Load A Mod");
	pMenuItem = menuFile->Append( ID_Save, "&Save", "Saves the map");
	pMenuItem->Enable(false);
	menuFile->Append( ID_SaveAs, "&Save As...", "Saves the map under a different file name");
    menuFile->AppendSeparator();
	menuFile->Append( ID_ImportMap, "&Import Map...", "");
	menuFile->Append( ID_ImportCivIII, "Import Civ III file...");
	menuFile->AppendSeparator();
    menuFile->Append( ID_Quit, "E&xit" );
	mMenuBar->Append( menuFile, "&File" );

	menuFile = new wxMenu;
	pMenuItem = menuFile->Append( ID_EditModProperties, "&Properties...", "Mod Properties");
	mMenuBar->Append( menuFile, "&Mod" );

	menuFile = new wxMenu;
	pMenuItem = menuFile->Append( ID_EditRules, "Edit &Rules...", "Edit Rules");
	pMenuItem->Enable(false);
	pMenuItem = menuFile->Append( ID_EditArtDefines, "Edit &Art Defines...", "Edit Art Defines");
	//pMenuItem->Enable(false);
	mMenuBar->Append( menuFile, "&Rules" );

	menuFile = new wxMenu;
	menuFile->Append( ID_ScenarioProperties, "Scenario Properties...", wxEmptyString );
	menuFile->AppendSeparator();
	menuFile->Append( ID_CustomRules, "Custom Rules", wxEmptyString, wxITEM_CHECK );
	mMenuBar->Append( menuFile, "&Scenario" );

    SetMenuBar( mMenuBar );

    CreateStatusBar();
    SetStatusText( "Welcome to IndieCiv" );

	m_mgr.SetManagedWindow(this);



    wxAuiToolBar* tb4 = new wxAuiToolBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
                                         wxAUI_TB_DEFAULT_STYLE);
    tb4->SetToolBitmapSize(wxSize(16,16));


	wxInitAllImageHandlers();

	wxBitmap temp;
	temp.LoadFile("Assets\\art\\ui\\TerrainSel.png", wxBITMAP_TYPE_PNG);

    //wxBitmap tb4_bmp1 = wxArtProvider::GetBitmap(wxART_NORMAL_FILE, wxART_OTHER, wxSize(16,16));
	//wxBitmap tb3_bmp1 = wxArtProvider::GetBitmap(wxART_FOLDER, wxART_OTHER, wxSize(16,16));
	tb4->AddTool(ID_TerrainMode, wxT("ID_TerrainMode"), temp, wxT("Right click to change the terrain type"), wxITEM_RADIO);
	tb4->ToggleTool ( ID_TerrainMode, true);

	temp.LoadFile("Assets\\art\\ui\\CitySel.png", wxBITMAP_TYPE_PNG);
	tb4->AddTool(ID_OverlayMode, wxT("ID_OverlayMode"), temp, wxT("Right click to change the overlay type"), wxITEM_RADIO);
	tb4->ToggleTool ( ID_OverlayMode, false);

	temp.LoadFile("Assets\\art\\ui\\CitySel.png", wxBITMAP_TYPE_PNG);
	tb4->AddTool(ID_ResourceMode, wxT("ID_ResourceMode"), temp, wxT("Right click to change the resource type"), wxITEM_RADIO);
	tb4->ToggleTool ( ID_OverlayMode, false);


	temp.LoadFile("Assets\\art\\ui\\CitySel.png", wxBITMAP_TYPE_PNG);
	tb4->AddTool(ID_CityMode, wxT("ID_CityMode"), temp, wxT("City - Right click to change the player"), wxITEM_RADIO);
	tb4->ToggleTool ( ID_CityMode, false);

	temp.LoadFile("Assets\\art\\ui\\CitySel.png", wxBITMAP_TYPE_PNG);
	tb4->AddTool(ID_TerritoryMode, wxT("ID_TerritoryMode"), temp, wxT("Territory - Right click to change the players"), wxITEM_RADIO);
	tb4->ToggleTool ( ID_TerritoryMode, false);

	tb4->AddSeparator();


	temp.LoadFile("Assets\\art\\ui\\ClearMap.png", wxBITMAP_TYPE_PNG);
	tb4->AddTool(ID_ClearMap, wxT("Clear Map"), temp, wxT("Clears the map with the currently selected terrain"));

	mMapWidth = new wxSpinCtrl( tb4, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 20, 9999, 20 );
	mMapWidth->Connect( wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler( MyFrame::OnChangeMapWidth ), NULL, this );

	tb4->AddControl ( mMapWidth, _("Map Width") );

	mMapHeight = new wxSpinCtrl( tb4, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 20, 9999, 20 );
	mMapHeight->Connect( wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler( MyFrame::OnChangeMapHeight ), NULL, this );
	tb4->AddControl ( mMapHeight, _("Map Height") );

	//tb4->AddTool(ID_DropDownToolbarItem + 1, wxT("test2"), temp, wxT("Radio 2"), wxITEM_RADIO);

    //tb4->AddTool(ID_DropDownToolbarItem+2, wxT("test3"), temp, wxNullBitmap, wxITEM_RADIO, wxT(""), wxT(""), NULL);
    //tb4->AddTool(ID_SampleItem+23, wxT("Item 2"), tb4_bmp1);
    //tb4->AddTool(ID_SampleItem+24, wxT("Item 3"), tb4_bmp1);
    //tb4->AddTool(ID_SampleItem+25, wxT("Item 4"), tb4_bmp1);
    //tb4->AddSeparator();
	//tb4->AddTool(ID_SampleItem+26, wxT("Item 5"), tb4_bmp1);
	//tb4->AddTool(ID_SampleItem+27, wxT("Item 6"), tb4_bmp1);
	//tb4->AddTool(ID_SampleItem+28, wxT("Item 7"), tb4_bmp1);
	//tb4->AddTool(ID_SampleItem+29, wxT("Item 8"), tb4_bmp1);
    //tb4->SetToolDropDown(ID_DropDownToolbarItem, true);
    //tb4->SetToolDropDown(ID_DropDownToolbarItem+1, true);
    //tb4->SetToolDropDown(ID_DropDownToolbarItem+2, true);
    //tb4->SetCustomOverflowItems(prepend_items, append_items);
    tb4->Realize();

	mMapView = new MapView(this, wxID_ANY);
    m_mgr.AddPane(tb4, wxAuiPaneInfo().
                  Name(wxT("tb4")).Caption(wxT("Big Toolbar")).
                  ToolbarPane().Top().
                  LeftDockable(false).RightDockable(false));

	new CGlobals();
	new CInput();
	CInput::getSingletonPtr()->init();

	this->mMod = new CMod();
	this->mMod->SetDirty ( true );

	new CCivIIIImport;
	new CLocaleInterface;
	CLocaleInterface::getSingletonPtr()->Load();
	new CMapCiv3Interface();
	CMapCiv3Interface::getSingletonPtr()->mShowStartLocations = true;
	new CDataInterface;
	new CXmlLoader;
	//new CPathFinding();
	if ( !CXmlLoader::getSingletonPtr()->LoadBasic() )
		return;
	if ( !CXmlLoader::getSingletonPtr()->Load() )
		return;

	this->mMod->Init();


	//((MapView*)mMapView)->MapViewInit();

	//wxPropertyGrid::RegisterAdditionalEditors();
	m_pSampleMultiButtonEditor = wxPropertyGrid::RegisterEditorClass(new wxMultiButtonTextCtrlEditor());

	m_pSampleXomboBoxCheckListBoxEditor = wxPropertyGrid::RegisterEditorClass(new wxComboBoxWithCheckListBox());

	mPropGrid = new wxPropertyGrid(
		this, // parent
		PGID, // id
		wxDefaultPosition, // position
		wxDefaultSize, // size
		// Here are just some of the supported window styles
		//wxPG_AUTO_SORT | // Automatic sorting after items added
		wxPG_SPLITTER_AUTO_CENTER | // Automatically center splitter until user manually adjusts it
		// Default style
		wxPG_DEFAULT_STYLE );

	//wxPGRegisterEditorClass( wxMultiButtonTextCtrlEditor );

	// Window style flags are at premium, so some less often needed ones are
	// available as extra window styles (wxPG_EX_xxx) which must be set using
	// SetExtraStyle member function. wxPG_EX_HELP_AS_TOOLTIPS, for instance,
	// allows displaying help strings as tool tips.
	mPropGrid->SetExtraStyle( wxPG_EX_HELP_AS_TOOLTIPS );

	mPropGrid->Append( new wxPropertyCategory("Tile Properties") );

	mPropGrid->Append( new wxIntProperty("X", wxPG_LABEL, 0) );
	mPropGrid->Append( new wxIntProperty("Y", wxPG_LABEL, 0) );
	// Terrain
	wxArrayString arr;
	for ( int i = 0; i < CDataInterface::getSingletonPtr()->getTerrainData().size; i++ )
	{
		CDataTerrain* pDataTerrain = CDataInterface::getSingletonPtr()->getTerrainData(i);
		irr::core::stringw t(pDataTerrain->GetLocale( pDataTerrain->mDescription ));

		arr.Add(t.c_str());
	}
	mPropGrid->Append( new wxEnumProperty("Terrain",wxPG_LABEL,arr) );

	// Relief/Overlay
	arr.Clear();
	arr.Add ( "None" );
	for ( int i = 0; i < CDataInterface::getSingletonPtr()->getReliefData().size; i++ )
	{
		CDataRelief* pDataRelief = CDataInterface::getSingletonPtr()->getReliefData(i);
		irr::core::stringw t ( pDataRelief->GetLocale( pDataRelief->mDescription ));

		arr.Add(t.c_str());
	}
	mPropGrid->Append( new wxEnumProperty("Overlay", wxPG_LABEL, arr) );

	// Resource
	arr.Clear();
	arr.Add ( "None" );
	for ( int i = 0; i < CDataInterface::getSingletonPtr()->getResourceData().size; i++ )
	{
		CDataResource* pDataResource = CDataInterface::getSingletonPtr()->getResourceData(i);
		irr::core::stringw t ( pDataResource->GetLocale( pDataResource->mDescription ));

		arr.Add(t.c_str());
	}
	mPropGrid->Append( new wxEnumProperty("Resource", wxPG_LABEL, arr) );

	// Tile Owner
	arr.Clear();
	arr.Add ( "None" );
	for ( irr::u32 i = 0; i < CGlobals::getSingletonPtr()->mPlayerList.size(); i++ )
	{
		CPlayer* pPlayer = CGlobals::getSingletonPtr()->mPlayerList[i];
		irr::core::stringw t(pPlayer->mCivilizationData->GetLocale( pPlayer->mCivilizationData->mDescription ));

		arr.Add(t.c_str());
	}
	mPropGrid->Append( new wxEnumProperty("Tile Owner",wxPG_LABEL,arr) );

	mPropGrid->Append( new wxPropertyCategory("Tile Improvements") );
	mPropGrid->Append( new wxBoolProperty("City", wxPG_LABEL, false) );

	//mPropGrid->Append( new wxBoolProperty("Irrigation", wxPG_LABEL, true) );
	//mPropGrid->Append( new wxBoolProperty("Mine", wxPG_LABEL, false) );
	//mPropGrid->Append( new wxBoolProperty("Road", wxPG_LABEL, false) );
	//mPropGrid->Append( new wxBoolProperty("Railroad", wxPG_LABEL, false) );


	// City?

	wxPGProperty* pid = mPropGrid->Append( new wxPropertyCategory("City Properties") );

	// Name
	mPropGrid->Append( new wxStringProperty("Name", wxPG_LABEL, "London") );

	// Owner
	arr.Clear();
	for ( irr::u32 i = 0; i < CGlobals::getSingletonPtr()->mPlayerList.size(); i++ )
	{
		CPlayer* pPlayer = CGlobals::getSingletonPtr()->mPlayerList[i];
		irr::core::stringw t(pPlayer->mCivilizationData->GetLocale( pPlayer->mCivilizationData->mDescription ));

		arr.Add(t.c_str());
	}
	mPropGrid->Append( new wxEnumProperty("Owner",wxPG_LABEL,arr) );

	mPropGrid->Append( new wxIntProperty("Size", wxPG_LABEL, 1) );


	pid = mPropGrid->AppendIn( pid, new wxPropertyCategory("City Improvements") );
	for ( int i = 0; i < CDataInterface::getSingletonPtr()->getCityImprovementData().size; i++ )
	{
		CDataCityImprovement* pData = CDataInterface::getSingletonPtr()->getCityImprovementData ( i );
		irr::core::stringw t ( pData->GetLocale( pData->mDescription ) );

		mPropGrid->Append ( new wxBoolProperty(t.c_str(), wxPG_LABEL, false) );
	}

	//mPropGrid->Append ( new wxMultiChoiceProperty("City Improvements", wxPG_LABEL ) );

	//mPropGrid->Append( new wxEnumProperty(wxT("City Improvements2"), wxPG_LABEL) );
	//mPropGrid->SetPropertyEditor( wxT("City Improvements2"), m_pSampleXomboBoxCheckListBoxEditor );


	mPropGrid->HideProperty ( "City Properties", true );

	// ******************************************************************************************************************************
	// UNIT PROPERTIES

	mPropGrid->Append( new wxPropertyCategory("Unit Properties") );

	mPropGrid->Append( new wxEnumProperty(wxT("Units"), wxPG_LABEL) );
	mPropGrid->SetPropertyEditor( wxT("Units"), m_pSampleMultiButtonEditor );

	arr.Clear();
	for ( irr::u32 i = 0; i < CDataInterface::getSingletonPtr()->getUnitData().size; i++ )
	{
		CDataUnit* pData = CDataInterface::getSingletonPtr()->getUnitData(i);
		irr::core::stringw t ( pData->GetLocale( pData->mDescription ) );

		arr.Add(t.c_str());
	}
	mPropGrid->Append( new wxEnumProperty("Unit Type", wxPG_LABEL, arr ) );
	mPropGrid->HideProperty ( "Unit Type", true );


	mPropGrid->Append ( new wxIntProperty ( "Unit Moves Left", wxPG_LABEL, 0 ) );
    mPropGrid->SetPropertyEditor( wxT("Unit Moves Left"), wxPGEditor_SpinCtrl );
    mPropGrid->SetPropertyAttribute( wxT("Unit Moves Left"), wxPG_ATTR_MIN, (long)0 );  // Use constants instead of string
    mPropGrid->SetPropertyAttribute( wxT("Unit Moves Left"), wxT("Step"), (long)1 );
    //pg->SetPropertyAttribute( wxT("Unit Moves Left"), wxT("MotionSpin"), true );
	mPropGrid->HideProperty ( "Unit Moves Left", true );



	mPropGrid->SetPropertyAttributeAll ( wxPG_BOOL_USE_CHECKBOX, true );
	//mPropGrid->SetMinSize(wxSize(400, -1));
	mPropGrid->SetInitialSize(wxSize(200, -1) );
	//mPropGrid->FitColumns();

	m_mgr.AddPane ( mPropGrid, wxAuiPaneInfo().Right() );
	m_mgr.AddPane ( mMapView, wxAuiPaneInfo().CenterPane() );
	m_mgr.Update();

	mMapView->SetFocus();
	this->SetTitle();

	((MapView*)mMapView)->MapViewInit();

	mSelectedTerrain		= CDataInterface::getSingletonPtr()->getTerrainData( 0 );
	mSelectedOverlay		= CDataInterface::getSingletonPtr()->getReliefData( 0 );
	mSelectedResource		= CDataInterface::getSingletonPtr()->getResourceData( 0 );
	//mSelectedCivilization	= CDataInterface::getSingletonPtr()->getCivilizationData( 0 );
	mSelectedPlayer			= CGlobals::getSingletonPtr()->mPlayerList[0];

	mMapEditorMode = EGameStateMapEditorMode_Terrain;
	mSelectedTile = NULL;
	this->SetSelectedTile ( CMapInterface::getSingletonPtr()->GetMapTile(0, 0) );
	this->OnTileSelected();





}

MyFrame::~MyFrame ( void )
{
	mMapWidth->Disconnect( wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler( MyFrame::OnChangeMapWidth ), NULL, this );
	mMapHeight->Disconnect( wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler( MyFrame::OnChangeMapHeight ), NULL, this );


	delete mMapView;

     m_mgr.UnInit();
}

void MyFrame::SetTitle ( void )
{
	wxString title;

	title = this->mMod->GetModTitle().c_str();

	if ( this->mMod->IsDirty() )
		title += "*";

	wxFrame::SetTitle ( title );
}

void MyFrame::OnShow ( wxShowEvent& event  )
{


}

void MyFrame::OnQuit ( wxCommandEvent& WXUNUSED(event) )
{
    Close(TRUE);
}

void MyFrame::OnEditModProperties ( wxCommandEvent& WXUNUSED(event) )
{
	ModPropertiesDialog modPropertiesDialog ( this );

	modPropertiesDialog.m_modTitle->SetLabel ( this->mMod->GetModTitle().c_str() );
	modPropertiesDialog.m_modAuthor->SetLabel ( this->mMod->GetModAuthor().c_str() );
	modPropertiesDialog.m_modVersion->SetLabel ( this->mMod->GetModVersion().c_str() );
	modPropertiesDialog.m_modDescription->SetLabel ( this->mMod->GetModDescription().c_str() );

	if ( modPropertiesDialog.ShowModal() == wxID_OK )
	{
		wxString str;

		str = modPropertiesDialog.m_modTitle->GetValue();
		this->mMod->SetModTitle ( (const char*)str.mb_str() );

		str = modPropertiesDialog.m_modAuthor->GetValue();
		this->mMod->SetModAuthor ( (const char*)str.mb_str() );

		str = modPropertiesDialog.m_modVersion->GetValue();
		this->mMod->SetModVersion ( (const char*)str.mb_str() );

		str = modPropertiesDialog.m_modDescription->GetValue();
		this->mMod->SetModDescription ( (const char*)str.mb_str() );

		this->mMod->SetDirty ( true );

		this->SetTitle();
	}
}

void MyFrame::OnEditRules ( wxCommandEvent& WXUNUSED(event) )
{
	RulesDialog rulesDialog ( this );
	rulesDialog.ShowModal();


	this->UpdatePG();

}

void MyFrame::OnEditArtDefines ( wxCommandEvent& WXUNUSED(event) )
{
	ArtDefinesDialog artDefinesDialog ( this );
	artDefinesDialog.ShowModal();


	//this->UpdatePG();
}

void MyFrame::OnScenarioProperties ( wxCommandEvent& WXUNUSED(event) )
{
	ScenarioPropertiesDialog scenarioProperties ( this, this->mMod );
	scenarioProperties.ShowModal();

}

void MyFrame::OnCustomRules ( wxCommandEvent& event )
{
	wxMenuItem* pMenuItem = mMenuBar->FindItem(ID_EditRules);

	if ( event.IsChecked() )
	{
		pMenuItem->Enable(true);
		this->mMod->SetCustomRules(true);
	}
	else
	{
		pMenuItem->Enable(false);
		this->mMod->SetCustomRules(false);
	}
}
 
void MyFrame::OnAbout ( wxCommandEvent& WXUNUSED(event) )
{

    wxMessageBox("This is a wxWindows Hello world sample",
        "About Hello World", wxOK | wxICON_INFORMATION, this);
}

void MyFrame::OnLoad ( wxCommandEvent& WXUNUSED(event) )
{
	wxDirDialog *OpenDialog = new wxDirDialog(
		this, _("Choose mod directory to load"), wxGetCwd() + "\\Mods", wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST );

	// Creates a "open file" dialog with 4 file types
	if (OpenDialog->ShowModal() == wxID_OK) // if the user click "Open" instead of "cancel"
	{
		//wxFileName::SplitPath ( OpenDialog->GetPath(), &cmd, NULL, NULL)

		// Get the selected directory path
		wxFileName fName = OpenDialog->GetPath();

		// Make relative to the game directory

		//fName.MakeRelativeTo ( wxGetCwd() + "\\Mods" );

		// Clear the game data
		CDataInterface::getSingletonPtr()->Shutdown();

		delete this->mMod;
		this->mMod = new CMod();

		this->mMod->SetModName ( fName.GetName() );
		this->mMod->SetModPath ( fName.GetFullPath().t_str() );

		this->mMod->LoadMod();

		this->SetTitle();
		wxMenuItem* pMenuItem = mMenuBar->FindItem(ID_Save);
		pMenuItem->Enable(true);

		//this->mMod->SetDirty ( true );



		// Set the mod path
		/*CXmlLoader::getSingletonPtr()->mMODPath = fName.GetFullPath().t_str();
		// Load the locale for the mod
		CLocaleInterface::getSingletonPtr()->LoadMOD ( (const char*)fName.GetFullPath() );
		// Load game data
		if ( !CXmlLoader::getSingletonPtr()->LoadBasic() )
			return;
		if ( !CXmlLoader::getSingletonPtr()->Load() )
			return;


		FILE* fp = fopen ( mCurrentFileName, "r" );

		if ( fp )
		{
			CMapInterface::getSingletonPtr()->Load ( fp );

			CMapCiv3Interface::getSingletonPtr()->SetTextures();
			CMapCiv3Interface::getSingletonPtr()->mDirty = true;

			fclose ( fp );
		}*/
	}
}


void MyFrame::OnSave ( wxCommandEvent& WXUNUSED(event) )
{
	this->mMod->SaveMod();
	this->SetTitle();

	/*FILE* fp = fopen ( mCurrentFileName, "w" );

	if ( fp )
	{
		CMapInterface::getSingletonPtr()->Save ( fp );

		fclose ( fp );
	}


	if ( !CXmlLoader::getSingletonPtr()->Save() )
	{
		return;
	}*/
}


void MyFrame::OnSaveAs ( wxCommandEvent& WXUNUSED(event) )
{
	wxDirDialog *saveDialog = new wxDirDialog(
		this, _("Choose directory to save mod"), wxGetCwd()  );

	// Creates a Save Dialog with 4 file types
	if (saveDialog->ShowModal() == wxID_OK) // If the user clicked "OK"
	{
		//mCurrentFileName = saveDialog->GetPath();

		wxFileName fName = saveDialog->GetPath();

		// Look for the mod info file
		wxString fFirst = fName.GetFullPath().t_str();
		fFirst += "\\*.indieciv";
		wxString f = wxFindFirstFile(fFirst);

		if ( !f.empty() )
		{
			wxMessageBox( _("The selected folder already contains a mod."), _("Error!"), wxOK | wxICON_INFORMATION, this );
		}
		else
		{
			this->mMod->SetModName ( fName.GetName() );
			this->mMod->SetModPath ( fName.GetFullPath().t_str() );

			// Make relative to the game directory
			//fName.MakeRelativeTo ( wxGetCwd() + "\\Mods" );

			this->mMod->SaveMod();
			this->SetTitle();

			wxMenuItem* pMenuItem = mMenuBar->FindItem(ID_Save);
			pMenuItem->Enable(true);
		}
	}

	// Clean up after ourselves
	saveDialog->Destroy();
}


void MyFrame::OnImportMap ( wxCommandEvent& WXUNUSED(event) )
{
	wxFileDialog *OpenDialog = new wxFileDialog ( this, _("Choose a file to open"), wxEmptyString, wxEmptyString, _("Map Files (*.map)|*.map"), wxFD_OPEN, wxDefaultPosition );

	// Creates a "open file" dialog with 4 file types
	if (OpenDialog->ShowModal() == wxID_OK) // if the user click "Open" instead of "cancel"
	{
		FILE* fp = fopen ( OpenDialog->GetPath(), "r" );

		if ( fp )
		{
			CMapInterface::getSingletonPtr()->Load ( fp );

			CMapCiv3Interface::getSingletonPtr()->SetTextures();
			CMapCiv3Interface::getSingletonPtr()->mDirty = true;

			fclose ( fp );

			this->SetSelectedTile ( CMapInterface::getSingletonPtr()->GetMapTile(0, 0) );
			this->OnTileSelected();

			this->mMapWidth->SetValue ( CMapInterface::getSingletonPtr()->mMapWidth );
			this->mMapHeight->SetValue ( CMapInterface::getSingletonPtr()->mMapHeight );

		}
	}
}


void MyFrame::OnImportCivIII ( wxCommandEvent& WXUNUSED(event) )
{
	wxFileDialog *OpenDialog = new wxFileDialog ( this, _("Choose a file to open"), wxEmptyString, wxEmptyString, _("All Files (*.*)|*.*"), wxFD_OPEN, wxDefaultPosition );

	// Creates a "open file" dialog with 4 file types
	if (OpenDialog->ShowModal() == wxID_OK) // if the user click "Open" instead of "cancel"
	{
		FILE* fp = fopen ( OpenDialog->GetPath(), "rb" );

		if ( fp )
		{
			CCivIIIImport::getSingletonPtr()->Import ( fp );

			fclose ( fp );
		}
	}
}


void MyFrame::OnTerrainSelect ( wxCommandEvent& event )
{
	if ( event.GetId() == ID_TerrainMode )
		this->mMapEditorMode = EGameStateMapEditorMode_Terrain;
	else if ( event.GetId() == ID_OverlayMode )
		this->mMapEditorMode = EGameStateMapEditorMode_Overlay;
	else if ( event.GetId() == ID_ResourceMode )
		this->mMapEditorMode = EGameStateMapEditorMode_Resource;
	else if ( event.GetId() == ID_CityMode )
		this->mMapEditorMode = EGameStateMapEditorMode_CityPlacement;
	else if ( event.GetId() == ID_TerritoryMode )
		this->mMapEditorMode = EGameStateMapEditorMode_Territory;

	if ( event.GetId() >= ID_PlayerSelectItem )
	{
		int idx = event.GetId() - ID_PlayerSelectItem;

		mSelectedPlayer = CGlobals::getSingletonPtr()->mPlayerList[idx];
	}
	else if ( event.GetId() >= ID_ResourceSelectItem )
	{
		int idx = event.GetId() - ID_ResourceSelectItem;

		mSelectedResource = CDataInterface::getSingletonPtr()->getResourceData( idx );
	}
	else if ( event.GetId() >= ID_OverlaySelectItem )
	{
		int idx = event.GetId() - ID_OverlaySelectItem;
	
		mSelectedOverlay = CDataInterface::getSingletonPtr()->getReliefData( idx );
	}
	else if ( event.GetId() >= ID_TerrainSelectItem )
	{
		int idx = event.GetId() - ID_TerrainSelectItem;

		mSelectedTerrain = CDataInterface::getSingletonPtr()->getTerrainData( idx );
	}

}

// ***************************************************************
// On Clear Map
// ***************************************************************
void MyFrame::OnClearMap ( wxCommandEvent& WXUNUSED(event) )
{
	CMapInterface::getSingletonPtr()->ClearMap ( this->mSelectedTerrain );
}

void MyFrame::OnChangeMapWidth( wxSpinEvent& event )
{
	int iX = 0;
	int iY = 0;

	if ( this->GetSelectedTile() )
	{
		iX = this->GetSelectedTile()->mTileX;
		iY = this->GetSelectedTile()->mTileY;

	}
	CMapInterface::getSingletonPtr()->Resize ( mMapWidth->GetValue(), mMapHeight->GetValue() ); 

	this->SetSelectedTile ( CMapInterface::getSingletonPtr()->GetMapTile(iX, iY) );
	this->OnTileSelected();
}
void MyFrame::OnChangeMapHeight( wxSpinEvent& event )
{
	int iX = 0;
	int iY = 0;

	if ( this->GetSelectedTile() )
	{
		iX = this->GetSelectedTile()->mTileX;
		iY = this->GetSelectedTile()->mTileY;

	}
	CMapInterface::getSingletonPtr()->Resize ( mMapWidth->GetValue(), mMapHeight->GetValue() ); 

	this->SetSelectedTile ( CMapInterface::getSingletonPtr()->GetMapTile(iX, iY) );
	this->OnTileSelected();
}

void MyFrame::OnDropDownToolbarItem ( wxAuiToolBarEvent& evt )
{
    //if (evt.IsDropDownClicked())
    {
        wxAuiToolBar* tb = static_cast<wxAuiToolBar*>(evt.GetEventObject());

        tb->SetToolSticky(evt.GetId(), true);
		tb->ToggleTool ( evt.GetId(), true);

        // create the popup menu
        wxMenu menuPopup;

        //wxBitmap bmp = wxArtProvider::GetBitmap(wxART_QUESTION, wxART_OTHER, wxSize(16,16));

		if ( evt.GetId() == ID_TerrainMode )
		{
			this->mMapEditorMode = EGameStateMapEditorMode_Terrain;
			for ( int i = 0; i < CDataInterface::getSingletonPtr()->getTerrainData().size; i++ )
			{
				CDataTerrain* pDataTerrain = CDataInterface::getSingletonPtr()->getTerrainData(i);
				irr::core::stringw t(pDataTerrain->GetLocale( pDataTerrain->mDescription ));
				
				wxMenuItem* m1 =  new wxMenuItem(&menuPopup, ID_TerrainSelectItem + i, t.c_str());
				//m1->SetBitmap(bmp);
				menuPopup.Append(m1);			
			}
		}
		else if ( evt.GetId() == ID_OverlayMode )
		{
			this->mMapEditorMode = EGameStateMapEditorMode_Overlay;
			for ( int i = 0; i < CDataInterface::getSingletonPtr()->getReliefData().size; i++ )
			{
				CDataRelief* pDataOverlay = CDataInterface::getSingletonPtr()->getReliefData(i);
				irr::core::stringw t(pDataOverlay->GetLocale( pDataOverlay->mDescription ));
				
				wxMenuItem* m1 =  new wxMenuItem(&menuPopup, ID_OverlaySelectItem + i, t.c_str());
				//m1->SetBitmap(bmp);
				menuPopup.Append(m1);			
			}
		}
		else if ( evt.GetId() == ID_ResourceMode )
		{
			this->mMapEditorMode = EGameStateMapEditorMode_Resource;
			for ( int i = 0; i < CDataInterface::getSingletonPtr()->getResourceData().size; i++ )
			{
				CDataResource* pDataResource = CDataInterface::getSingletonPtr()->getResourceData(i);
				irr::core::stringw t(pDataResource->GetLocale( pDataResource->mDescription ));

				wxMenuItem* m1 =  new wxMenuItem(&menuPopup, ID_ResourceSelectItem + i, t.c_str());
				//m1->SetBitmap(bmp);
				menuPopup.Append(m1);			
			}
		}

		if ( evt.GetId() == ID_CityMode || evt.GetId() == ID_TerritoryMode )
		{
			if ( evt.GetId() == ID_CityMode )
				this->mMapEditorMode = EGameStateMapEditorMode_CityPlacement;
			if ( evt.GetId() == ID_TerritoryMode )
				this->mMapEditorMode = EGameStateMapEditorMode_Territory;

			for ( irr::u32 i = 0; i < CGlobals::getSingletonPtr()->mPlayerList.size(); i++ )
			{
				CPlayer* pPlayer = CGlobals::getSingletonPtr()->mPlayerList[i];
				irr::core::stringw t(pPlayer->mCivilizationData->GetLocale( pPlayer->mCivilizationData->mDescription ));
				
				wxMenuItem* m1 =  new wxMenuItem(&menuPopup, ID_PlayerSelectItem + i, t.c_str());
				//m1->SetBitmap(bmp);
				menuPopup.Append(m1);			
			}
		}

        // line up our menu with the button
        wxRect rect = tb->GetToolRect(evt.GetId());
        wxPoint pt = tb->ClientToScreen(rect.GetBottomLeft());
        pt = ScreenToClient(pt);


        PopupMenu(&menuPopup, pt);


        // make sure the button is "un-stuck"
        tb->SetToolSticky(evt.GetId(), false);
    }
}

void MyFrame::UpdatePG ( void )
{

	wxPGProperty* pg = mPropGrid->GetProperty ("City Improvements");
	pg->DeleteChildren();


	//pid = mPropGrid->AppendIn( pid, new wxPropertyCategory("City Improvements") );
	for ( int i = 0; i < CDataInterface::getSingletonPtr()->getCityImprovementData().size; i++ )
	{
		CDataCityImprovement* pData = CDataInterface::getSingletonPtr()->getCityImprovementData ( i );
		irr::core::stringw t ( pData->GetLocale( pData->mDescription ) );

		bool bState = false;
		if ( this->mSelectedTile->mCity )
		{
			if ( this->mSelectedTile->mCity->IsImprovementBuilt ( pData ) )
				bState = true;
			else
				bState = false;
		}
		mPropGrid->AppendIn ( pg, new wxBoolProperty(t.c_str(), wxPG_LABEL, bState) );
	}

	mPropGrid->SetPropertyAttributeAll ( wxPG_BOOL_USE_CHECKBOX, true );
	mPropGrid->Refresh();
}


// ***************************************************************
// On Tile Selected
// ***************************************************************
void MyFrame::OnTileSelected ( void )
{
	irr::core::stringw t;

	CMapTile* pMapTile = this->GetSelectedTile();

	if ( pMapTile )
	{
		mPropGrid->Enable();

		mPropGrid->HideProperty ( "Tile Properties", false );
		mPropGrid->HideProperty ( "City Properties", false );
		mPropGrid->HideProperty ( "Tile Improvements", false );
		mPropGrid->HideProperty ( "Unit Properties", false );
		mPropGrid->EnableProperty ( "Tile Owner" );

		mPropGrid->SetPropertyValue( "X", pMapTile->mTileX );
		mPropGrid->SetPropertyValue( "Y", pMapTile->mTileY );

		t = pMapTile->mTerrainType->GetLocale( pMapTile->mTerrainType->mDescription );
		mPropGrid->SetPropertyValue ( "Terrain", t.c_str() );

		if ( pMapTile->mReliefType )
		{
			irr::core::stringw t ( pMapTile->mReliefType->GetLocale( pMapTile->mReliefType->mDescription ));

			mPropGrid->SetPropertyValue ( "Overlay", t.c_str() );
		}
		else
		{
			mPropGrid->SetPropertyValue ( "Overlay", "None" );
		}

		if ( pMapTile->mOwner )
		{
			irr::core::stringw t( pMapTile->mOwner->mCivilizationData->GetLocale( pMapTile->mOwner->mCivilizationData->mDescription ));

			mPropGrid->SetPropertyValue ( "Tile Owner", t.c_str() );
		}
		else
		{
			mPropGrid->SetPropertyValue ( "Tile Owner", "None" );
		}

		if ( pMapTile->mResourceType )
		{
			irr::core::stringw t ( pMapTile->mResourceType->GetLocale( pMapTile->mResourceType->mDescription ));

			mPropGrid->SetPropertyValue ( "Resource", t.c_str() );
		}
		else
		{
			mPropGrid->SetPropertyValue ( "Resource", "None" );
		}

		if ( pMapTile->mCity )
		{
			mPropGrid->SetPropertyValue ( "City", true );
			mPropGrid->HideProperty ( "City Properties", false );
			mPropGrid->DisableProperty ( "Tile Owner" );

			for ( int i = 0; i < CDataInterface::getSingletonPtr()->getCityImprovementData().size; i++ )
			{
				CDataCityImprovement* pData = CDataInterface::getSingletonPtr()->getCityImprovementData ( i );
				irr::core::stringw t ( pData->GetLocale( pData->mDescription ) );

				if ( pMapTile->mCity->IsImprovementBuilt ( pData ) )
					mPropGrid->SetPropertyValue ( t.c_str(), true );
				else
					mPropGrid->SetPropertyValue ( t.c_str(), false );
			}
		}
		else
		{
			mPropGrid->SetPropertyValue ( "City", false );
			mPropGrid->HideProperty ( "City Properties", true );
		}

		wxPGProperty* prop = mPropGrid->GetProperty("Units");
		wxPGChoices newChoices;
		for ( int i = 0; i < pMapTile->mUnitList.size; i++ )
		{
			CUnit* pUnit = pMapTile->mUnitList[i];
			irr::core::stringw t ( pUnit->mUnitData->GetLocale( pUnit->mUnitData->mDescription ) );

			newChoices.Add ( t.c_str());
		}
		prop->SetChoices(newChoices);


		if ( pMapTile->mUnitList.size > 0 )
			mPropGrid->HideProperty ( "Unit Type", false );
		else
			mPropGrid->HideProperty ( "Unit Type", true );

		//mPropGrid->SetPropertyValue ( "Unit Moves Left", false );
	}
	else
	{
		mPropGrid->HideProperty ( "Tile Properties", true );
		mPropGrid->HideProperty ( "City Properties", true );
		mPropGrid->HideProperty ( "Tile Improvements", true );
		mPropGrid->HideProperty ( "Unit Properties", true );
		mPropGrid->HideProperty ( "Unit Type", true );

		mPropGrid->Disable();
	}

}

// ***************************************************************
// On PG Changed
// ***************************************************************
void MyFrame::OnPGChanged ( wxPropertyGridEvent& event )
{
	if ( event.GetPropertyName() == "Terrain" )
	{
		CDataTerrain* pDataTerrain = CDataInterface::getSingletonPtr()->getTerrainData( event.GetProperty()->GetValue().GetInteger() );

		this->GetSelectedTile()->mTerrainType = pDataTerrain;//mSelectedTerrain;
		CMapCiv3Interface::getSingletonPtr()->SmoothTile ( this->GetSelectedTile() );

		CMapCiv3Interface::getSingletonPtr()->SetTexturesTile ( this->GetSelectedTile(), 2);
		CMapCiv3Interface::getSingletonPtr()->mDirty = true;

		this->mMod->SetDirty ( true );
		this->mMod->SetCustomMap ( true );
	}
	else if ( event.GetPropertyName() == "Overlay" )
	{
		CDataRelief* pDataRelief = CDataInterface::getSingletonPtr()->getReliefData( event.GetProperty()->GetValue().GetInteger() - 1 );

		this->GetSelectedTile()->mReliefType = pDataRelief;//mSelectedTerrain;
		CMapCiv3Interface::getSingletonPtr()->SmoothTile ( this->GetSelectedTile() );

		CMapCiv3Interface::getSingletonPtr()->SetTexturesTile ( this->GetSelectedTile(), 2);
		CMapCiv3Interface::getSingletonPtr()->mDirty = true;

		this->mMod->SetDirty ( true );
		this->mMod->SetCustomMap ( true );
	}
	else if ( event.GetPropertyName() == "Resource" )
	{
		CDataResource* pDataResource = CDataInterface::getSingletonPtr()->getResourceData( event.GetProperty()->GetValue().GetInteger() - 1 );

		this->GetSelectedTile()->mResourceType = pDataResource;//mSelectedTerrain;
		CMapCiv3Interface::getSingletonPtr()->SmoothTile ( this->GetSelectedTile() );

		CMapCiv3Interface::getSingletonPtr()->SetTexturesTile ( this->GetSelectedTile(), 2);
		CMapCiv3Interface::getSingletonPtr()->mDirty = true;

		this->mMod->SetDirty ( true );
		this->mMod->SetCustomMap ( true );
	}
	else if ( event.GetPropertyName() == "Tile Owner" )
	{
		if ( event.GetProperty()->GetValue().GetInteger() == 0 )
		{
			this->GetSelectedTile()->mOwner = NULL;
		}
		else
		{
			CPlayer* pPlayer = CGlobals::getSingletonPtr()->mPlayerList [ event.GetProperty()->GetValue().GetInteger() - 1 ];
			this->GetSelectedTile()->mOwner = pPlayer;
		}
		CMapCiv3Interface::getSingletonPtr()->mDirty = true;
		this->mMod->SetDirty ( true );
		this->mMod->SetCustomMap ( true );
	}
	else if ( event.GetPropertyName() == "Owner" )
	{
		CPlayer* pPlayer = CGlobals::getSingletonPtr()->mPlayerList [ event.GetProperty()->GetValue().GetInteger() ];
		this->GetSelectedTile()->mOwner = pPlayer;

		irr::core::stringw t( pPlayer->mCivilizationData->GetLocale( pPlayer->mCivilizationData->mDescription ));
		mPropGrid->SetPropertyValue ( "Tile Owner", t.c_str() );

		CMapCiv3Interface::getSingletonPtr()->mDirty = true;
		this->mMod->SetDirty ( true );
		this->mMod->SetCustomMap ( true );
	}
	else if ( event.GetPropertyName() == "City" )
	{
		if ( event.GetProperty()->GetValue().GetBool() == true )
		{
			CCity* pCity = new CCity;

			pCity->mOwnerIdx = 0;

			this->GetSelectedTile()->mOwner = CGlobals::getSingletonPtr()->mPlayerList [ pCity->mOwnerIdx ];
			irr::core::stringw t( this->GetSelectedTile()->mOwner->mCivilizationData->GetLocale( this->GetSelectedTile()->mOwner->mCivilizationData->mDescription ));
			mPropGrid->SetPropertyValue ( "Tile Owner", t.c_str() );
			this->GetSelectedTile()->mCity = pCity;

			for ( int i = 0; i < CDataInterface::getSingletonPtr()->getCityImprovementData().size; i++ )
			{
				CDataCityImprovement* pData = CDataInterface::getSingletonPtr()->getCityImprovementData ( i );
				irr::core::stringw t ( pData->GetLocale( pData->mDescription ) );

				mPropGrid->SetPropertyValue ( t.c_str(), false );
			}

			CMapCiv3Interface::getSingletonPtr()->mDirty = true;

			mPropGrid->HideProperty ( "City Properties", false );

			mPropGrid->DisableProperty ( "Tile Owner" );
		}
		else
		{
			if ( this->GetSelectedTile()->mCity )
			{
				delete this->GetSelectedTile()->mCity;
				this->GetSelectedTile()->mCity = NULL;
				this->GetSelectedTile()->mOwner = NULL;

				CMapCiv3Interface::getSingletonPtr()->mDirty = true;
			}

			mPropGrid->HideProperty ( "City Properties", true );
			mPropGrid->EnableProperty ( "Tile Owner" );

		}
		this->mMod->SetDirty ( true );
		this->mMod->SetCustomMap ( true );
	}
	else if ( event.GetPropertyName() == "Unit Type" )
	{
		CDataUnit* pData = CDataInterface::getSingletonPtr()->getUnitData ( event.GetProperty()->GetValue().GetInteger() );

		wxPGProperty* prop = mPropGrid->GetProperty("Units");

		CUnit* pUnit = this->GetSelectedTile()->mUnitList [ prop->GetChoiceSelection() ];

		pUnit->ChangeUnitType ( pData );
	}
	else
	{
		for ( int i = 0; i < CDataInterface::getSingletonPtr()->getCityImprovementData().size; i++ )
		{
			CDataCityImprovement* pData = CDataInterface::getSingletonPtr()->getCityImprovementData ( i );
			irr::core::stringw t ( pData->GetLocale( pData->mDescription ) );

			if ( event.GetPropertyName() == t.c_str() )
			{
				if ( event.GetProperty()->GetValue().GetBool() == true )
				{
					this->GetSelectedTile()->mCity->mImprovementBuiltList.Add ( pData );
				}
				else
				{
					this->GetSelectedTile()->mCity->mImprovementBuiltList.Remove ( pData );
				}
			}
		}
	}

	mPropGrid->Refresh();
}


void MyFrame::OnPropertyGridButtonClick ( wxCommandEvent& e )
{
	wxPGProperty* prop = mPropGrid->GetSelection();
	//wxStatusBar* sb = GetStatusBar();
	if ( prop )
	{
		wxString text(wxT("Button clicked: "));
		text += mPropGrid->GetPropertyLabel(prop);
		text += wxT(", name=");
		text += mPropGrid->GetPropertyName(prop);
		//sb->SetStatusText( text );
	}
	else
	{
		::wxMessageBox(wxT("SHOULD NOT HAPPEN!!!"));
	}
}